<template>
  <div class="marquee" ref="marqueeRef">{{ text.replace(/\<br\>/g, " ") }}</div>
</template>

<script lang="ts" setup>
import { watch, ref, nextTick } from "vue"

type Props = {
  text: string
}
const props = defineProps<Props>()
const emits = defineEmits(["next"])

const marqueeRef = ref<HTMLDivElement>()
const rafRef = ref(0) // requestAnimateFrame 实例
const textWidth = ref(0) // 轮播文字长度
const parentWidth = ref(0) // 父盒子长度
const waitPx = ref(20) // 轮播完成给予的空距离
const tX = ref(0) // 当前位移的距离 translateX
// 可配置项
const speed = ref(0.5) // 速率 越大越快
const times = ref(0) // 轮播次数
const time = ref(10 * 1000) // 如果长度不够轮播 就展示的秒数

const move = () => {
  if (!marqueeRef.value) return
  times.value = 0
  const width = marqueeRef.value.offsetWidth
  parentWidth.value = marqueeRef.value.parentElement?.offsetWidth || 300
  if (width <= parentWidth.value) {
    // 文字小于就不轮播
    marqueeRef.value.style.transform = `translateX(${0}px)`
    setTimeout(() => {
      emits("next")
    }, time.value);
    return
  }
  tX.value = parentWidth.value / 2
  textWidth.value = width + waitPx.value
  marqueeRef.value.style.transform = `translateX(${ tX.value }px)`
  scroll()
}

const scroll = () => {
  if (!marqueeRef.value) return
  rafRef.value = requestAnimationFrame(() => {
    tX.value -= speed.value
    if (Math.abs(tX.value) >= textWidth.value) {
      tX.value = parentWidth.value
      // 设置轮播次数 超过就暂停
      times.value += 1
      if (times.value >= 2) {
        emits("next")
        return cancelAnimationFrame(rafRef.value)
      }
    }
    // const s = v / speed.value % textWidth.value
    marqueeRef.value!.style.transform = `translateX(${tX.value}px)`
    scroll()
  })
}

watch(() => props.text, () => {
  nextTick(() => {
    move()
  })
})

</script>

<style lang="less" scoped>
.marquee {
  display: inline-block;
}
</style>